home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_100 / 172_01 / ytab.c < prev    next >
Text File  |  1980-01-01  |  26KB  |  948 lines

  1. /*
  2.   HEADER:              CUG  nnn.nn;
  3.   TITLE:               LEX - A Lexical Analyser Generator
  4.   VERSION:             1.1 for IBM-PC
  5.   DATE:                Jan 30, 1985
  6.   DESCRIPTION:         A Lexical Analyser Generator. From UNIX
  7.   KEYWORDS:            Lexical Analyser Generator YACC C PREP
  8.   SYSTEM:              IBM-PC and Compatiables
  9.   FILENAME:            YTAB.C
  10.   WARNINGS:            This program is not for the casual user. It will
  11.                        be useful primarily to expert developers.
  12.   CRC:                 N/A
  13.   SEE-ALSO:            YACC and PREP
  14.   AUTHORS:             Charles H. Forsyth
  15.                        Scott Guthery 11100 leafwood lane Austin, TX 78750
  16.                        Andrew M. Ward, Jr.  Houston, Texas (Modifications)
  17.   COMPILERS:           LATTICE C
  18.   REFERENCES:          UNIX Systems Manuals -- Lex Manual on distribution disks
  19. */
  20. /*
  21.  * Copyright (c) 1978 Charles H. Forsyth
  22.  *
  23.  * Modified 02-Dec-80 Bob Denny -- Conditionalize debug code for reduced size
  24.  * Modified 29-May-81 Bob Denny -- Clean up overlay stuff for RSX.
  25.  * More     19-Mar-82 Bob Denny -- New C library & compiler
  26.  * More     03-May-82 Bob Denny -- Final touches, remove unreferenced autos
  27.  * More     29-Aug-82 Bob Denny -- Clean up -d printouts
  28.  * More     29-Aug-82 Bob Denny -- Reformat for readability and comment
  29.  *                                 while learning about LEX.
  30.  * More     20-Nov-83 Scott Guthery -- Adapt for IBM PC & DeSmet C
  31.  *
  32.  * Modified 22-Jun-86 Andrew Ward -- Modified code to compile under Lattice C
  33.  *                                 version 3.0h.  Corrected several errors
  34.  *                                 from the assumption that pointers and
  35.  *                                 integers are the same size.     
  36.  *                                 New debug code for LATTICE C using assert
  37.  *                                 to test for wild pointers.
  38.  */
  39.  
  40. #include <stdio.h>
  41. #include <assert.h>
  42. #include <stdlib.h>
  43. #include <string.h>
  44. #include "lexlex.h"
  45.  
  46. char    ccl[ (NCHARS+1) / NBPC ];
  47. int  sz_ccl = (NCHARS+1) / NBPC;
  48.     char *yysterm[] = {
  49.        "error",
  50.        "NAME",
  51.        "CCLASS",
  52.        "STRING",
  53.        "CONCAT",
  54.        0     };
  55.     extern char *progname;
  56.     extern char *breakc;
  57.     extern char *ignore;
  58.     extern char *illeg;
  59.     extern int  nlook;
  60.     char *lalloc();
  61.     struct des {
  62.        struct nfa *d_start;
  63.        struct nfa *d_final;
  64.     };
  65.     struct nlist {
  66.        struct  nlist   *nl_next;
  67.        struct  nfa     *nl_base;
  68.        struct  nfa     *nl_end;
  69.        struct  nfa     *nl_start;
  70.        struct  nfa     *nl_final;
  71.        char    *nl_name;
  72.     }
  73.     *nlist;
  74.     extern  int str_len;
  75.     extern  struct  nfa     *nfap;
  76.     extern  struct  nfa     *elem(int, char *);
  77.     extern  struct  des     *newdp(struct nfa *, struct nfa *);
  78.     extern  struct  nlist   *lookup(char *);
  79.     extern int     mapc(int);
  80.     extern int     cclass(void);
  81.     extern void    name(int);
  82.     extern void    action(void);
  83.     extern void    skipstr(int);
  84.     extern void    copycode(void);
  85.     extern void    string(int);
  86.     extern void    copynfa(struct nlist *, struct nfa *, struct des *);
  87.     extern void    spccl(char *, char *, struct des *, char **);
  88.     extern void    unget( int );
  89.     extern void    copy(char *, char *, int);
  90.     extern void    errmsg(char *);
  91.     extern void    yyerror(char *, char *);
  92.     extern void    newcase(int);
  93.     extern void    llactr(void);
  94.     extern void    setline(void);
  95.     extern void    cclprint(char *);
  96.     extern  int     yyline;
  97.  
  98. typedef union  {
  99.     char   *buff;
  100.     struct nlist *list;
  101.     struct des   *des_ptr;
  102.     struct nfa   *elem_ptr;
  103. } YYSTYPE;
  104. #define NAME 257
  105. #define CCLASS 258
  106. #define STRING 259
  107. #define CONCAT 260
  108. #define yyclearin yychar = -1
  109. #define yyerrok yyerrflag = 0
  110. extern int yychar;
  111. extern short yyerrflag;
  112. #ifndef YYMAXDEPTH
  113. #define YYMAXDEPTH 150
  114. #endif
  115. YYSTYPE yylval, yyval;
  116.  
  117.     struct nfa *np, *nbase;
  118.     char *cp;
  119.     struct des *dp, *dp1;
  120.     struct trans *tp;
  121.     struct nlist *nl;
  122.     int i, c;
  123.     #define YYERRCODE 256
  124.  
  125.  
  126.     /*
  127.  * Lexical analyser
  128.  * (it isn't done with lex...)
  129.  */
  130.        char    buffer[150];
  131.  
  132. int yylex()
  133.     {
  134.  
  135.        int c;
  136.        /*      char *cp; */
  137.        int lno;
  138.  
  139.        if (yyline == 0)
  140.            yyline++;
  141. loop:
  142.        c = get();
  143.        if (isupper(c)) {
  144.            name(c);
  145.            yylval.buff = strlwr( yylval.buff );
  146.            return(STRING);
  147.        }
  148.        else if (islower(c) || c == '_') {
  149.            name(c);
  150.            return(NAME);
  151.        }
  152.        switch (c) {
  153.        case EOF:
  154.            return(0);
  155.  
  156.        case '[':
  157.            return(cclass());
  158.  
  159.        case '(':
  160.        case ')':
  161.        case '{':
  162.        case '}':
  163.        case '*':
  164.        case '|':
  165.        case '=':
  166.        case ';':
  167.        case '%':
  168.            return(c);
  169.  
  170.        case '/':
  171.            if ((c = get()) != '*') {
  172.                unget(c);
  173.                return('/');
  174.            }
  175.            lno = yyline;
  176.            for (; c != EOF; c = get())
  177.                if (c == '*')
  178.                    if ((c = get()) == '/')
  179.                        goto loop;
  180.                    else
  181.                        unget(c);
  182.            yyline = lno;
  183.            errmsg("End of file in comment");
  184.  
  185.        case '\'':
  186.        case '"':
  187.            yylval.buff = buffer;
  188.            string(c);
  189.            return(STRING);
  190.  
  191.        case '\n':
  192.        case '\r':
  193.        case ' ':
  194.        case '\t':
  195.            goto loop;
  196.  
  197.        default:
  198.  
  199.            yylval.buff = buffer;
  200. /*         if (c == '\\') {
  201.                unget(c);
  202.                c = mapch(EOF);
  203.            }
  204. */
  205.            buffer[0] = c;
  206.            buffer[1] = '\0';
  207.            str_len = 1;
  208.            return(STRING);
  209.        }
  210. /* ERR: Warning 85: function return value mismatch */
  211.     }
  212.  
  213.  
  214. int cclass()
  215.     {
  216.        int c, i, lc;
  217.        int compl;
  218.  
  219.        compl = 0;
  220.        /* Zero the ccl array */
  221.        for (i = 0; i < sz_ccl; i++)  ccl[i] = '\0';
  222.        /* Check if exclusion definition */
  223.        if ((c = get()) == '^') compl++;
  224.        else  unget(c);
  225.  
  226.        lc = -1;
  227.        while( ( c = mapc(']') ) != EOF)
  228.        {
  229.            if (c == '-' && lc >= 0)
  230.            {
  231.                if((c = mapc(']')) == EOF)   break;
  232.                /* Map 'c' into bit pattern */
  233.                for(i = lc; i <= c; i++)  ccl[ i / NBPC ] |= 1 << (i % NBPC);
  234.                lc = -1;
  235.                continue;
  236.            }
  237.  
  238.            ccl[ c / NBPC ] |= 1 << ( c % NBPC );
  239.            lc = c;
  240.        }
  241.  
  242.        if (compl) {
  243.            for (i = 0; i < sz_ccl; i++)
  244.                ccl[i] ^= -1;
  245.            if (aflag == 0)
  246.                for (i = 0200; i < ( 1 << NBPC ); i++)
  247.                    ccl[i/NBPC] &= ~(1 << (i%NBPC));
  248.        }
  249.        yylval.buff = newccl( ccl );
  250.        return(CCLASS);
  251.     }
  252.  
  253. void string(ec)
  254. int ec;
  255.     {
  256.        char *cp;
  257.        int c;
  258.        extern int str_len;
  259.        for(cp = buffer; (c = mapc(ec)) != EOF;)
  260.            *cp++ = c;
  261.        *cp = '\0';
  262.        str_len = strlen( buffer );
  263.     }
  264.  
  265. int mapc(ec)
  266.        int ec;
  267.     {
  268.  
  269.        int c, v, i;
  270.  
  271.        if((c = get()) == ec)  return(EOF);
  272.        switch(c) {
  273.        case EOF:
  274.            errmsg("End of file in string");
  275.            return(c);
  276.  
  277.        case '\\':
  278.            if ((c = get()) >= '0' && c <= '7') {
  279.                i = 0;
  280.                for (v = 0; c>='0' && c<='7' && i++<3; c = get())
  281.                    v = v*010 + c-'0';
  282.                unget(c);
  283.                return(v&CMASK);
  284.            }
  285.            switch (c) {
  286.            case 'n':
  287.                return('\n');
  288.  
  289.            case 't':
  290.                return('\t');
  291.  
  292.            case 'b':
  293.                return('\b');
  294.  
  295.            case 'r':
  296.                return('\r');
  297.  
  298.            case '\n':
  299.                yyline++;
  300.                return(mapc(ec));
  301.            }
  302.  
  303.        default:
  304.        }
  305.        return(c);
  306.     }
  307.  
  308. void name(c)
  309.        int c;
  310.     {
  311.        char *cp;